package com.leon.datalink.web.controller;

import com.leon.datalink.core.persistence.PersistenceConfigManager;
import com.leon.datalink.web.model.PersistenceConfig;
import com.leon.datalink.web.model.PersistenceStatus;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.HashMap;
import java.util.Map;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
 * PersistenceController测试类
 */
@RunWith(SpringRunner.class)
public class PersistenceControllerTest {

    @InjectMocks
    private PersistenceController persistenceController;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        // 初始化PersistenceConfigManager
        PersistenceConfigManager.getInstance().initialize();
    }

    @Test
    public void testGetStatus() {
        // 测试获取状态
        ResponseEntity<PersistenceStatus> response = persistenceController.getStatus();
        
        assertNotNull(response);
        assertEquals(200, response.getStatusCodeValue());
        
        PersistenceStatus status = response.getBody();
        assertNotNull(status);
        assertTrue(status.isGlobalEnabled());
        assertEquals("selective", status.getStrategy());
        assertNotNull(status.getStoragePath());
        assertNotNull(status.getActorTypeConfigs());
        assertNotNull(status.getInstanceConfigs());
    }

    @Test
    public void testUpdateGlobalConfig() {
        // 准备测试数据
        Map<String, Object> config = new HashMap<>();
        config.put("globalEnabled", false);
        config.put("strategy", "all");
        config.put("storagePath", "/custom/path");
        
        // 执行测试
        ResponseEntity<String> response = persistenceController.updateGlobalConfig(config);
        
        // 验证结果
        assertNotNull(response);
        assertEquals(200, response.getStatusCodeValue());
        assertEquals("Global configuration updated successfully", response.getBody());
    }

    @Test
    public void testUpdateActorTypeConfig() {
        // 准备测试数据
        Map<String, Object> config = new HashMap<>();
        config.put("actorType", "com.leon.datalink.test.TestActor");
        config.put("enabled", true);
        
        // 执行测试
        ResponseEntity<String> response = persistenceController.updateActorTypeConfig(config);
        
        // 验证结果
        assertNotNull(response);
        assertEquals(200, response.getStatusCodeValue());
        assertEquals("Actor type configuration updated successfully", response.getBody());
        
        // 验证配置是否生效
        PersistenceConfigManager manager = PersistenceConfigManager.getInstance();
        assertTrue(manager.shouldPersist("com.leon.datalink.test.TestActor", "test-instance", "TestMessage"));
    }

    @Test
    public void testUpdateInstanceConfig() {
        // 准备测试数据
        Map<String, Object> config = new HashMap<>();
        config.put("instanceId", "test-instance-001");
        config.put("enabled", false);
        
        // 执行测试
        ResponseEntity<String> response = persistenceController.updateInstanceConfig(config);
        
        // 验证结果
        assertNotNull(response);
        assertEquals(200, response.getStatusCodeValue());
        assertEquals("Instance configuration updated successfully", response.getBody());
    }

    @Test
    public void testUpdateAdvancedConfig() {
        // 准备测试数据
        PersistenceConfig config = new PersistenceConfig();
        config.setSnapshotInterval(1000);
        config.setEventRetentionCount(5000);
        config.setMessageBlacklist("HeartbeatMessage,PingMessage");
        
        // 执行测试
        ResponseEntity<String> response = persistenceController.updateAdvancedConfig(config);
        
        // 验证结果
        assertNotNull(response);
        assertEquals(200, response.getStatusCodeValue());
        assertEquals("Advanced configuration updated successfully", response.getBody());
    }

    @Test
    public void testInvalidActorTypeConfig() {
        // 准备无效测试数据
        Map<String, Object> config = new HashMap<>();
        config.put("enabled", true);
        // 缺少actorType
        
        // 执行测试
        ResponseEntity<String> response = persistenceController.updateActorTypeConfig(config);
        
        // 验证结果
        assertNotNull(response);
        assertEquals(400, response.getStatusCodeValue());
        assertTrue(response.getBody().contains("Actor type is required"));
    }

    @Test
    public void testInvalidInstanceConfig() {
        // 准备无效测试数据
        Map<String, Object> config = new HashMap<>();
        config.put("enabled", true);
        // 缺少instanceId
        
        // 执行测试
        ResponseEntity<String> response = persistenceController.updateInstanceConfig(config);
        
        // 验证结果
        assertNotNull(response);
        assertEquals(400, response.getStatusCodeValue());
        assertTrue(response.getBody().contains("Instance ID is required"));
    }

    @Test
    public void testExceptionHandling() {
        // 测试异常处理
        Map<String, Object> config = new HashMap<>();
        config.put("globalEnabled", "invalid_boolean"); // 无效的布尔值
        
        try {
            ResponseEntity<String> response = persistenceController.updateGlobalConfig(config);
            // 应该能够处理异常并返回错误响应
            assertNotNull(response);
            assertTrue(response.getStatusCodeValue() >= 400);
        } catch (Exception e) {
            // 如果抛出异常，也是可以接受的
            assertNotNull(e.getMessage());
        }
    }

    @Test
    public void testConfigurationPersistence() {
        // 测试配置的持久性
        PersistenceConfigManager manager = PersistenceConfigManager.getInstance();
        
        // 设置配置
        manager.setActorTypePersistence("com.leon.datalink.test.PersistentActor", true);
        manager.setInstancePersistence("persistent-instance", true);
        
        // 验证配置
        assertTrue(manager.shouldPersist("com.leon.datalink.test.PersistentActor", "any-instance", "TestMessage"));
        assertTrue(manager.shouldPersist("any.actor.Type", "persistent-instance", "TestMessage"));
        
        // 测试消息过滤
        assertFalse(manager.shouldPersistMessage("HeartbeatMessage"));
        assertTrue(manager.shouldPersistMessage("DataProcessedEvent"));
    }
}
